#include "h264_ctx.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "encoder_logger.h"
#include "pixel.h"
#include "cabac.h"

int init_h264_ctx(input_img_ctx_t *input_ctx, h264_ctx_t *ctx)
{
    if (input_ctx == NULL || ctx == NULL) {
        ERR_LOG("Input args is null.\n");
        return -1;
    }

    ctx->input_ctx = input_ctx;
    ctx->encode_frame.plane_data[H264_LUMA_PLANE] = calloc(1, ctx->input_ctx->width * ctx->input_ctx->height);
    ctx->encode_frame.plane_data[H264_CHROMA_PLANE] = calloc(1, ctx->input_ctx->width * ctx->input_ctx->height / 2);
    memcpy(ctx->encode_frame.plane_data[H264_LUMA_PLANE], input_ctx->plane.y_data, ctx->input_ctx->width * ctx->input_ctx->height);
    plane_copy_interleave(ctx->encode_frame.plane_data[H264_CHROMA_PLANE], input_ctx->plane.u_data, input_ctx->plane.v_data, 
        ctx->input_ctx->width / 2, ctx->input_ctx->height / 2);

    ctx->encode_frame.mb_height = (ctx->input_ctx->height + H264_MB_SIZE - 1) / H264_MB_SIZE;
    ctx->encode_frame.mb_width = (ctx->input_ctx->width + H264_MB_SIZE - 1) / H264_MB_SIZE;
    ctx->encode_frame.width = ctx->input_ctx->width;
    ctx->encode_frame.height = ctx->input_ctx->height;

    DEBUG_LOG("width mb num %d height mb num %d.\n", ctx->encode_frame.mb_width, ctx->encode_frame.mb_height);

    int ret = bs_init(&ctx->bs);
    if (ret != 0) {
        ERR_LOG("bs_init failed ret %d.\n", ret);
        return ret;
    }

    init_sps(&ctx->sps, &ctx->encode_frame);
    init_pps(&ctx->pps, &ctx->encode_frame);

    ctx->cur_mb.i_mb_width = ctx->sps.i_mb_width;
    ctx->cur_mb.i_mb_height = ctx->sps.i_mb_height;
    ctx->cur_mb.i_mb_count = ctx->cur_mb.i_mb_width * ctx->cur_mb.i_mb_height;
    h264_cqm_init(&ctx->quant, 16);
    h264_cabac_init();
    return 0;
}